const fs = require('fs');
const path = require("path");
const crypto = require('./crypto');

// 创建多级目录
function mkdirsSync(dirname) {
    if (fs.existsSync(dirname)) {
        return true;
    } else {
        if (mkdirsSync(path.dirname(dirname))) {
            fs.mkdirSync(dirname);
            return true;
        }
    }
}

// 下载Sticker包
async function downloadStickerSet(bot, chatId, replyMessageId, setName) {
    mkdirsSync(`stickers/${setName}`);
    await bot.sendMessage(chatId, '获取 Sticker 包信息', {
        reply_to_message_id: replyMessageId,
    });
    const stickerSet = await bot.getStickerSet(setName);

    for (let idx = 0; idx < stickerSet.stickers.length; idx++) {
        const sticker = stickerSet.stickers[idx];
        await bot.sendMessage(chatId, `正在下载 Sticker 文件 [${idx+1}/${stickerSet.stickers.length}]`, {
            reply_to_message_id: replyMessageId,
        });
        stickerSet.stickers[idx].file_path = await bot.downloadFile(sticker.file_id, `stickers/${setName}`);
    }
    return stickerSet;
}

// 加密Sticker包
async function encryptStickerSet(bot, chatId, replyMessageId, manifest, stickerSet) {
    const iv = crypto.getRandomBytes(16);
    const packKey = crypto.getRandomBytes(32);
    const encryptionKey = await crypto.deriveStickerPackKey(packKey);

    await bot.sendMessage(chatId, '正在加密 Manifest 文件', {
        reply_to_message_id: replyMessageId,
    });
    const { ciphertext } = await crypto.encryptAttachment(
        crypto.concatenateBytes(manifest),
        encryptionKey,
        iv
    );
    const hexKey = crypto.hexFromBytes(packKey);
    const base64Key = crypto.base64FromBytes(packKey);

    for (let idx = 0; idx < stickerSet.stickers.length; idx++) {
        const sticker = stickerSet.stickers[idx];
        const data = fs.readFileSync(sticker.file_path);

        await bot.sendMessage(chatId, `正在加密 Sticker 文件 [${idx+1}/${stickerSet.stickers.length}]`, {
            reply_to_message_id: replyMessageId,
        });
        const { ciphertext } = await crypto.encryptAttachment(
            crypto.concatenateBytes(data),
            encryptionKey,
            iv
        );
        sticker.encrypted = ciphertext;
    }
    return { hexKey, base64Key, encryptedManifest: ciphertext, stickerSet };
}

module.exports = { downloadStickerSet, encryptStickerSet };
